package arcane.object.gui.scroll;

import java.awt.Graphics2D;
import java.awt.Scrollbar;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

public class ScrollPanel<T> extends ListModel<T> implements AdjustmentListener {
	ScrollBar verticalBar;

	public ScrollPanel(int x, int y, int w, int h) {
		super(null, x, y);
		setSize(w, h);
		verticalBar = new ScrollBar(x + w - 1, y, h, Scrollbar.VERTICAL);
		verticalBar.addAdjustmentListener(this);
		validate();
	}

	public ScrollBar getVerticalBar() {
		return verticalBar;
	}

	public void add(T obj) {
		super.add(obj);
		validate();
	}

	public boolean remove(T obj) {
		boolean b = super.remove(obj);
		validate();
		return b;
	}

	public void update(long time) {
		super.update(time);
		verticalBar.update(time);
	}

	public void render(Graphics2D g, int x, int y) {
		super.render(g, x, y);
		verticalBar.render(g);
	}

	public void adjustmentValueChanged(AdjustmentEvent e) {
		int type = e.getAdjustmentType();
		int id = e.getID();
		int oldY = visibleY;
		if (type == AdjustmentEvent.UNIT_INCREMENT
				|| type == AdjustmentEvent.BLOCK_INCREMENT) {
			if (id == ScrollBar.HORIZONTAL_BAR)
				visibleX += e.getValue();
			else if (id == ScrollBar.VERTICAL_BAR){
				visibleY += e.getValue();
			}
		} else if (type == AdjustmentEvent.UNIT_DECREMENT
				|| type == AdjustmentEvent.BLOCK_DECREMENT) {
			if (id == ScrollBar.HORIZONTAL_BAR)
				visibleX -= e.getValue();
			else if (id == ScrollBar.VERTICAL_BAR)
				visibleY -= e.getValue();
		}
		if (visibleY < 0 || visibleY + height > calculateVerticalArea())
			visibleY=oldY;
		validate();
	}

	public void validate() {
		int calcH = calculateVerticalArea();
		if (calcH > height) {
			if (calcH > height * 2)
				verticalBar.knob.setHeight(10);
			else
				verticalBar.knob.setHeight(calcH - height);
		}
		if (calcH > 0) {
			verticalBar.knob.setY(((double) height / calcH)
					* verticalBar.getY());
		}
	}
}
